package com.zyx.settlement.server.service.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.rabbitmq.client.*;
import com.zyx.settlement.server.common.enums.SettlementStatus;
import com.zyx.settlement.server.model.dto.OrderMessageDTO;
import com.zyx.settlement.server.model.po.SettlementPO;
import com.zyx.settlement.server.service.ISettlementService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.Date;
import java.util.concurrent.TimeoutException;

/**
 * @author Yaxi.Zhang
 * @since 2022/10/22 08:37
 */
@Slf4j
@Service
public class OrderMessageService {

    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    private ISettlementService settlementService;

    DeliverCallback deliverCallback = (consumerTag, message) -> {
        String messageBody = new String(message.getBody());
        log.info("deliverCallback:messageBody:{}", messageBody);
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("81.68.117.201");
        try {
            OrderMessageDTO orderMessageDTO = objectMapper.readValue(messageBody, OrderMessageDTO.class);
            log.info("handleOrderService:orderSettlementDTO:{}", orderMessageDTO);
            SettlementPO settlementPO = new SettlementPO();
            settlementPO.setAmount(orderMessageDTO.getPrice());
            settlementPO.setDate(new Date());
            settlementPO.setOrderId(orderMessageDTO.getOrderId());
            settlementPO.setStatus(SettlementStatus.SUCCESS);
            settlementPO.setTransactionId(settlementService.settlement(orderMessageDTO.getAccountId(), orderMessageDTO.getPrice()));
            settlementService.save(settlementPO);
            orderMessageDTO.setSettlementId(settlementPO.getId());
            log.info("handleOrderService:settlementOrderDTO:{}", orderMessageDTO);

            try (Connection connection = connectionFactory.newConnection();
                 Channel channel = connection.createChannel()) {
                String messageToSend = objectMapper.writeValueAsString(orderMessageDTO);
                channel.basicPublish("exchange.settlement.order", "key.order", null, messageToSend.getBytes());
            }
        } catch (JsonProcessingException | TimeoutException e) {
            e.printStackTrace();
        }
    };

    @Async
    public void handleMessage() throws IOException, TimeoutException, InterruptedException {
        log.info("start linstening message");
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("81.68.117.201");
        try (Connection connection = connectionFactory.newConnection();
             Channel channel = connection.createChannel()) {

            channel.exchangeDeclare(
                    "exchange.order.settlement", BuiltinExchangeType.FANOUT, true, false, null);
            channel.queueDeclare("queue.settlement", true, false, false, null);
            channel.queueBind("queue.settlement", "exchange.order.settlement", "key.settlement");
            channel.basicConsume("queue.settlement", true, deliverCallback, consumerTag -> {
            });

            while (true) {
                Thread.sleep(100000);
            }
        }
    }

}
